package com.jackrain.nea.core.service;

import com.alibaba.dubbo.config.annotation.Service;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.jackrain.nea.core.api.AdTableAddCmd;
import com.jackrain.nea.core.db.Tools;
import com.jackrain.nea.core.entity.AdTableModel;
import com.jackrain.nea.core.mapper.AdLimitValueGroupMapper;
import com.jackrain.nea.core.mapper.AdTableMapper;
import com.jackrain.nea.core.mapper.AdTableSqlMapper;
import com.jackrain.nea.core.mapper.MapperShortcut;
import com.jackrain.nea.core.schema.Table;
import com.jackrain.nea.core.utility.CommandData;
import com.jackrain.nea.exception.NDSException;
import com.jackrain.nea.sys.CommandAdapter;
import com.jackrain.nea.util.ValueHolder;
import com.jackrain.nea.web.face.User;
import com.jackrain.nea.web.query.QuerySession;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

@Slf4j
@Component
@Service(protocol = "dubbo", validation = "true", version = "1.0", group = "ad")
public class AdTableAddCmdImpl extends CommandAdapter implements AdTableAddCmd {

    @Autowired
    private MapperShortcut mapperShortcut;
    @Autowired
    private AdTableMapper adTableMapper;
    @Autowired
    private AdLimitValueGroupMapper adLimitValueGroupMapper;
    @Autowired
    private AdTableSqlMapper adTableSqlMapper;

    @Autowired
    private AdRefbyTableAddCmdImpl adRefbyTableAddCmdImpl;

    @Transactional
    @Override
    public ValueHolder execute(QuerySession session) throws NDSException {

        CommandData data = new CommandData(session);


        JSONArray jar = data.getItemData("AD_REFBYTABLE", false);


        if (jar != null && !jar.isEmpty()) {
            return adRefbyTableAddCmdImpl.execute(session);

        }

        User user = session.getUser();
        int userid = user.getId();
        int ad_clientid = user.getClientId();
        int ad_orgid = user.getOrgId();
        long objectId = Tools.getSequence("AD_TABLE");
        JSONObject model = data.getMainData("AD_TABLE", true);
        model.put("ID", objectId);
        model.put("ISACTIVE", "Y");
        model.put("AD_CLIENT_ID", ad_clientid);
        model.put("AD_ORG_ID", ad_orgid);
        String name = model.getString("NAME");

        if (name == null || name.length() == 0) {
            return data.error(-1, "表名", "不能为空");
        }
        if (adTableMapper.exists(name)) {
            return data.error(-1, "表名", "已存在");
        }
        data.setInsertDefaultValue(model);
        mapperShortcut.insert(model, "AD_TABLE");

        log.debug(model.toJSONString());

        String v_mask = model.getString("MASK");
        int ad_tablecategoryid = model.getInteger("AD_TABLECATEGORY_ID");
        int parent_tableid = com.jackrain.nea.util.Tools.getInt(model.getInteger("PARENT_TABLE_ID"), -1);
        long directoryid = com.jackrain.nea.util.Tools.getLong(model.getLong("DIRECTORY_ID"), -1);

        String desc = model.getString("DESCRIPTION");
        int ORDERNO = com.jackrain.nea.util.Tools.getInt(model.getInteger("ORDERNO"), -1);

        //check mask
        if (!v_mask.matches("[AMDSQPGUVB]+")) {
            throw data.exception("Table mask must be in 'AMDSQPGUVB', input is:", v_mask);
        }
        // 如果包含批量修改(B) 但不包括修改(M) 则抛出异常
        if(v_mask.contains("B") && !v_mask.contains("M")){
            throw data.exception("If the table mask existed 'B' Then must be exists 'M'");
        }

        //序号排列
        if (ORDERNO < 1) {
            int orderno = adTableMapper.getMaxOrderNoByCategory(ad_tablecategoryid);
            adTableMapper.updateOrderNo(objectId, orderno);
        }

//        if (!name.toLowerCase().endsWith("item")) {
//
        if (directoryid <= 0) {
            directoryid = Tools.getSequence("DIRECTORY");
            JSONObject map = new JSONObject();
            map.put("ID", directoryid);
            map.put("NAME", name + "_LIST");
            map.put("DESCRIPTION", desc);
            map.put("ad_tablecategory_id", ad_tablecategoryid);
            //map.put("URL", "/html/nds/sheet/listframeset.jsp?table=" + name);
            map.put("ad_table_id", objectId);
            map.put("ISACTIVE", "Y");
            data.setInsertDefaultValue(model);
            mapperShortcut.insert(map, "directory");
            adTableMapper.updateDirectoryId(objectId, directoryid);
        }
//
//        }

//去除父表和安全目录
//        if (directoryid < 0 && parent_tableid < 0) {
//            throw data.exception("必须设置父表或安全目录");
//        }
        //insert into  AD_TABLESQL
        JSONObject map = new JSONObject();
        map.put("ID", Tools.getSequence("AD_TABLESQL"));
        map.put("AD_CLIENT_ID", ad_clientid);
        map.put("AD_ORG_ID", ad_orgid);
        map.put("AD_TABLE_ID", objectId);
        map.put("ISACTIVE", "Y");
        data.setInsertDefaultValue(model);
        mapperShortcut.insert(map, "AD_TABLESQL");

        //exec ddl
        String ddl = "create table " + name + "(id bigint(20) not null, ad_client_id bigint(10)," + "ad_org_id bigint(10), ownerid bigint(10),modifierid bigint(10), " + "creationdate datetime default NULL, modifieddate datetime default NULL,primary key(id))";
        adTableSqlMapper.DDLLog(objectId, ddl);
        //adTableSqlMapper.DDLLog(objectId, "create index idx_" + name + "_01 on " + name + "(ad_client_id)");

        //insert column
        long v_colId = Tools.getSequence("ad_column");
        map = new JSONObject();
        map.put("ID", v_colId);
        map.put("AD_CLIENT_ID", ad_clientid);
        map.put("NAME", name + ".ID");
        map.put("AD_TABLE_ID", objectId);
        map.put("AD_ORG_ID", ad_orgid);
        map.put("ISACTIVE", "Y");
        map.put("DESCRIPTION", "ID");
        map.put("ORDERNO", 1);
        map.put("COLTYPE", "number(20)");
        map.put("NULLABLE", "N");
        map.put("MASK", "0000000000");
        map.put("OBTAINMANNER", "pk");
        map.put("MODIFIABLE", "N");
        map.put("ISSYSTEM", "Y");
        map.put("DBNAME", "ID");
        map.put("ISAK", "Y");
        map.put("ISDK", "Y");
        data.setInsertDefaultValue(model);
        mapperShortcut.insert(map, "ad_column");


        //update table ak pk dk
        adTableMapper.updatePkAkDk(objectId, v_colId, v_colId, v_colId);

        //insert AD_CLIENT_ID
        AdTableModel table = adTableMapper.selectByTableName("AD_CLIENT");
        map = new JSONObject();
        map.put("ID", Tools.getSequence("ad_column"));
        map.put("AD_CLIENT_ID", ad_clientid);
        map.put("NAME", name + ".AD_CLIENT_ID");
        map.put("REF_TABLE_ID", table.getId());
        map.put("REF_COLUMN_ID", table.getPkColumnId());
        map.put("AD_TABLE_ID", objectId);
        map.put("AD_ORG_ID", ad_orgid);
        map.put("DESCRIPTION", "所属公司");
        map.put("ISACTIVE", "Y");
        map.put("ORDERNO", 2);
        map.put("COLTYPE", "number(10)");
        map.put("NULLABLE", "Y");
        map.put("MASK", "0000000000");
        map.put("OBTAINMANNER", "object");
        map.put("DEFAULTVALUE", "$AD_Client_ID$");
        map.put("MODIFIABLE", "N");
        map.put("DISPLAYTYPE", "text");
        map.put("DISPLAYROWS", "1");
        map.put("DISPLAYCOLS", "1");
        map.put("DISPLAYWIDTH", "20");
        map.put("ISSYSTEM", "Y");
        map.put("DBNAME", "AD_CLIENT_ID");
        map.put("ISAK", "N");
        map.put("ISDK", "N");
        data.setInsertDefaultValue(model);
        mapperShortcut.insert(map, "ad_column");

        //insert adorg
        table = adTableMapper.selectByTableName("AD_ORG");
        map = new JSONObject();
        map.put("ID", Tools.getSequence("ad_column"));
        map.put("AD_CLIENT_ID", ad_clientid);
        map.put("NAME", name + ".AD_ORG_ID");
        map.put("REF_TABLE_ID", table.getId());
        map.put("REF_COLUMN_ID", table.getPkColumnId());
        map.put("AD_TABLE_ID", objectId);
        map.put("AD_ORG_ID", ad_orgid);
        map.put("DESCRIPTION", "所属组织");
        map.put("ISACTIVE", "Y");
        map.put("ORDERNO", 3);
        map.put("COLTYPE", "number(10)");
        map.put("NULLABLE", "Y");
        map.put("MASK", "0000000000");
        map.put("OBTAINMANNER", "object");
        map.put("DEFAULTVALUE", "$AD_ORG_ID$");
        map.put("MODIFIABLE", "N");
        map.put("DISPLAYTYPE", "text");
        map.put("DISPLAYROWS", "1");
        map.put("DISPLAYCOLS", "1");
        map.put("DISPLAYWIDTH", "20");
        map.put("ISSYSTEM", "Y");
        map.put("DBNAME", "AD_ORG_ID");
        map.put("ISAK", "N");
        map.put("ISDK", "N");
        data.setInsertDefaultValue(model);
        mapperShortcut.insert(map, "ad_column");


        //日志
        map = new JSONObject();
        map.put("ID", Tools.getSequence("ad_column"));
        map.put("AD_CLIENT_ID", ad_clientid);
        map.put("NAME", name.toUpperCase() + ".(" + name.toUpperCase() + ".ID+100)");
        map.put("AD_TABLE_ID", objectId);
        map.put("AD_ORG_ID", ad_orgid);
        map.put("DBNAME", "(" + name.toUpperCase() + ".ID+100)");
        map.put("DESCRIPTION", "日志");
        map.put("ISACTIVE", "Y");
        map.put("ORDERNO", 1000);
        map.put("COLTYPE", "varchar2(30)");
        map.put("NULLABLE", "Y");
        map.put("MASK", "0010011001");
        map.put("OBTAINMANNER", "trigger");
        map.put("DEFAULTVALUE", "");
        map.put("MODIFIABLE", "N");
        map.put("DISPLAYTYPE", "hr");
        map.put("ISSYSTEM", "Y");
        map.put("ISAK", "N");
        map.put("ISDK", "N");
        data.setInsertDefaultValue(model);
        mapperShortcut.insert(map, "ad_column");


        //OWNERID
        table = adTableMapper.selectByTableName("USERS");
        map = new JSONObject();
        map.put("ID", Tools.getSequence("ad_column"));
        map.put("AD_CLIENT_ID", ad_clientid);
        map.put("NAME", name + ".OWNERID");
        map.put("REF_TABLE_ID", table.getId());
        map.put("REF_COLUMN_ID", table.getPkColumnId());
        map.put("AD_TABLE_ID", objectId);
        map.put("AD_ORG_ID", ad_orgid);
        map.put("DESCRIPTION", "创建人");
        map.put("ISACTIVE", "Y");
        map.put("ORDERNO", 1001);
        map.put("COLTYPE", "number(10)");
        map.put("NULLABLE", "Y");
        map.put("MASK", "0010001001");
        map.put("OBTAINMANNER", "operate");
        map.put("MODIFIABLE", "N");
        map.put("DISPLAYTYPE", "text");
        map.put("DISPLAYROWS", "1");
        map.put("DISPLAYCOLS", "1");
        map.put("DISPLAYWIDTH", "20");
        map.put("ISSYSTEM", "Y");
        map.put("DBNAME", "OWNERID");
        map.put("ISAK", "N");
        map.put("ISDK", "N");
        data.setInsertDefaultValue(model);
        mapperShortcut.insert(map, "ad_column");


        //MODIFIERID
        map = new JSONObject();
        map.put("ID", Tools.getSequence("ad_column"));
        map.put("AD_CLIENT_ID", ad_clientid);
        map.put("NAME", name + ".MODIFIERID");
        map.put("REF_TABLE_ID", table.getId());
        map.put("REF_COLUMN_ID", table.getPkColumnId());
        map.put("AD_TABLE_ID", objectId);
        map.put("AD_ORG_ID", ad_orgid);
        map.put("DESCRIPTION", "修改人");
        map.put("ISACTIVE", "Y");
        map.put("ORDERNO", 1002);
        map.put("COLTYPE", "number(10)");
        map.put("NULLABLE", "Y");
        map.put("MASK", "0010001001");
        map.put("OBTAINMANNER", "operate");
        map.put("MODIFIABLE", "N");
        map.put("DISPLAYTYPE", "text");
        map.put("DISPLAYROWS", "1");
        map.put("DISPLAYCOLS", "1");
        map.put("DISPLAYWIDTH", "20");
        map.put("ISSYSTEM", "Y");
        map.put("DBNAME", "MODIFIERID");
        map.put("ISAK", "N");
        map.put("ISDK", "N");
        data.setInsertDefaultValue(model);
        mapperShortcut.insert(map, "ad_column");

        //CREATIONDATE
        map = new JSONObject();
        map.put("ID", Tools.getSequence("ad_column"));
        map.put("AD_CLIENT_ID", ad_clientid);
        map.put("NAME", name + ".CREATIONDATE");
        map.put("AD_TABLE_ID", objectId);
        map.put("AD_ORG_ID", ad_orgid);
        map.put("DESCRIPTION", "创建时间");
        map.put("ISACTIVE", "Y");
        map.put("ORDERNO", 1003);
        map.put("COLTYPE", "datetime");
        map.put("NULLABLE", "");
        map.put("MASK", "0010001001");
        map.put("OBTAINMANNER", "sysdate");
        map.put("MODIFIABLE", "N");
        map.put("DISPLAYTYPE", "text");
        map.put("DISPLAYROWS", "1");
        map.put("DISPLAYCOLS", "1");
        map.put("DISPLAYWIDTH", "20");
        map.put("ISSYSTEM", "Y");
        map.put("DBNAME", "CREATIONDATE");
        map.put("ISAK", "N");
        map.put("ISDK", "N");
        data.setInsertDefaultValue(model);
        mapperShortcut.insert(map, "ad_column");


        //MODIFIEDDATE
        map = new JSONObject();
        map.put("ID", Tools.getSequence("ad_column"));
        map.put("AD_CLIENT_ID", ad_clientid);
        map.put("NAME", name + ".MODIFIEDDATE");
        map.put("AD_TABLE_ID", objectId);
        map.put("AD_ORG_ID", ad_orgid);
        map.put("DESCRIPTION", "修改时间");
        map.put("ISACTIVE", "Y");
        map.put("ORDERNO", 1004);
        map.put("COLTYPE", "datetime");
        map.put("NULLABLE", "");
        map.put("MASK", "0010001001");
        map.put("OBTAINMANNER", "sysdate");
        map.put("MODIFIABLE", "N");
        map.put("DISPLAYTYPE", "text");
        map.put("DISPLAYROWS", "1");
        map.put("DISPLAYCOLS", "1");
        map.put("DISPLAYWIDTH", "20");
        map.put("ISSYSTEM", "Y");
        map.put("DBNAME", "MODIFIEDDATE");
        map.put("ISAK", "N");
        map.put("ISDK", "N");
        data.setInsertDefaultValue(model);
        mapperShortcut.insert(map, "ad_column");


        //ISACTIVE
        long getid = adLimitValueGroupMapper.selectYESNOId();
        map = new JSONObject();
        map.put("ID", Tools.getSequence("ad_column"));
        map.put("AD_CLIENT_ID", ad_clientid);
        map.put("NAME", name + ".ISACTIVE");
        map.put("AD_LIMITVALUE_GROUP_ID", getid);
        map.put("AD_TABLE_ID", objectId);
        map.put("AD_ORG_ID", ad_clientid);
        map.put("DESCRIPTION", "可用");
        map.put("ISACTIVE", "Y");
        map.put("ORDERNO", 10000);
        map.put("COLTYPE", "char(1)");
        map.put("MASK", "0011101000");
        map.put("OBTAINMANNER", "select");
        map.put("MODIFIABLE", "N");
        map.put("DISPLAYTYPE", "check");
        map.put("DISPLAYROWS", "1");
        map.put("DISPLAYCOLS", "1");
        map.put("DISPLAYWIDTH", "20");
        map.put("ISSYSTEM", "Y");
        map.put("DBNAME", "ISACTIVE");
        map.put("ISAK", "N");
        map.put("ISDK", "N");
        data.setInsertDefaultValue(model);
        mapperShortcut.insert(map, "ad_column");

        log.debug(data.success().toJSONObject().toJSONString());

        return data.isInserting() ? data.success(objectId, "AD_TABLE") : data.success();
    }


}
